package fumec.br.ia.algoritmo;

import java.util.ArrayList;

import fumec.br.ia.search.Estado;
import fumec.br.ia.search.IAcao;
import fumec.br.ia.search.IFranja;
import fumec.br.ia.search.No;
import fumec.br.ia.search.Problema;
import fumec.br.ia.search.Solucao;

public class AStarSearch {
	private ArrayList<No> fechados = new ArrayList<No>();
	
	public Solucao buscaEmGrafo(Problema problema, IFranja franja){
		No primeiro = new No(new Estado(problema));
		primeiro.setCusto(0.0);
		primeiro.setProfundidade(0);
		franja.insere(primeiro);
		
		while(!franja.vazia()){
			No no = franja.removePrimeiro();
			
			if(no.getEstado().isObjetivo()){
				return new Solucao(no);
			};
			franja.insere(expandeNo(no));
			fechados.add(no);
		}
		return new Solucao(null);
	}
	
	public ArrayList<No> expandeNo(No no){
		ArrayList<No> nos = new ArrayList<No>();
		
		ArrayList<IAcao> acoes = no.getEstado().acoesValidas();
		
		for(int i = 0; i < acoes.size(); i++){
			if(!isFechado(no)){
				No novoNo = new No(no.getEstado().executa(acoes.get(i)));
				novoNo.setPai(no);
				novoNo.setProfundidade(no.getProfundidade()+1);
				novoNo.setCusto(no.getCusto() + acoes.get(i).getCusto());
				novoNo.setAcao(acoes.get(i));
				nos.add(novoNo);
			}
		}
		
		return nos;
	}
	
	private boolean isFechado(No no){
		for(int i = 0; i < fechados.size(); i++){
			if(no.getAcao() != null && fechados.get(i).getAcao() != null && no.getAcao().getDestino() == fechados.get(i).getAcao().getDestino()){
				return true;
			};
		}
		return false;
	}
}